package com.cx.pull.service;

import com.cx.pull.vo.QuestionVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * PullDataServiceImpl
 *
 * @author chenXin
 * @date 2024/02/27 11:42
 **/
@Slf4j
@Service
public class PullDataService {

    /**
     * 爬取stackoverflow数据
     *
     * @author: chenXin
     * @param pageNum
     * @date: 2024/2/27
     * @return
     */
    public List<QuestionVO> pullQuestions(Integer pageNum) {
        // 获取数据
        // 1. 尝试抓取亚stackoverflow页面 https://stackoverflow.com/questions?tab=newest&page=1前2页的所有questions（注意页面有分页），
        // 每条 question 包含（标题，内容，几条answer，多少views，多少votes，提问者姓名， 提问者名声， 提问时间 等，
        // 如 osefmaster 3 asked Nov 18, 2021 at 10:03中 姓名: osefmaster, 名声: 3, 提问时间: Nov 18, 2021 at 10:03 ）

        HttpClient client = HttpClients.createDefault();
        String baseUrl = "https://stackoverflow.com/questions?tab=newest&page=";

        // 默认爬取2页
        pageNum = Optional.ofNullable(pageNum).orElse(2);

        List<QuestionVO> resultList = new ArrayList<>();
        for (int i = 1; i <= pageNum; i++) {
            HttpGet request = new HttpGet(baseUrl + i);

            // 设置一些请求头信息来伪装成正常的浏览器访问
            request.setHeader("User-Agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3");
            request.setHeader("Accept",
                "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
            request.setHeader("Accept-Language", "en-US,en;q=0.5");

            HttpResponse response;
            try {
                response = client.execute(request);
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    String html = EntityUtils.toString(entity);
                    Document document = Jsoup.parse(html);

                    // 组装数据
                    Elements questions = document.select(".js-post-summary");
                    for (Element element : questions) {
                        Element stats = element.selectFirst(".s-post-summary--stats");
                        int voteCount =
                            Integer.parseInt(stats.selectFirst(".s-post-summary--stats-item-number").text());
                        int answerCount =
                            Integer.parseInt(stats.select(".s-post-summary--stats-item-number").get(1).text());
                        int viewCount =
                            Integer.parseInt(stats.select(".s-post-summary--stats-item-number").get(2).text());

                        Element content = element.selectFirst(".s-post-summary--content");
                        String title = content.selectFirst(".s-post-summary--content-title a").text();
                        String contentText = content.selectFirst(".s-post-summary--content-excerpt").text();

                        Element userCard = content.selectFirst(".s-user-card");
                        String askerName = userCard.selectFirst(".s-user-card--info .s-user-card--link").text();
                        String reputationScore = userCard.selectFirst(".s-user-card--rep").text();
                        String askedTime = userCard.selectFirst(".s-user-card--time").text().replace("asked ", "");

                        // 封装对象 放入集合中
                        QuestionVO question =
                            new QuestionVO(title, contentText, answerCount, viewCount, voteCount, askerName,
                                reputationScore, askedTime);
                        resultList.add(question);
                    }
                }
            } catch (IOException e) {
                log.warn("获取第{}页数据异常！ 异常信息：", i, e);
            }
        }

        return resultList;
    }

}